append_node_depth--;
}
+static gboolean
+should_reuse_node (BroadwayOutput *output,
+ BroadwayNode *node,
+ BroadwayNode *old_node)
+{
+ int i;
+ guint32 new_texture;
+
+ if (old_node->reused)
+ return FALSE;
+
+ if (node->type != old_node->type)
+ return FALSE;
+
+ if (broadway_node_equal (node, old_node))
+ return TRUE;
+
+ switch (node->type) {
+ case BROADWAY_NODE_TRANSFORM:
+#ifdef DEBUG_NODE_SENDING
+ g_print ("Patching transform node %d/%d\n",
+ old_node->id, old_node->output_id);
+#endif
+ append_uint32 (output, BROADWAY_NODE_OP_PATCH_TRANSFORM);
+ append_uint32 (output, old_node->output_id);
+ for (i = 0; i < node->n_data; i++)
+ append_uint32 (output, node->data[i]);
+ return TRUE;
+
+ case BROADWAY_NODE_TEXTURE:
+ /* Check that the size, etc is the same */
+ for (i = 0; i < 4; i++)
+ if (node->data[i] != old_node->data[i])
+ return FALSE;
+
+ new_texture = node->data[4];
+
+#ifdef DEBUG_NODE_SENDING
+ g_print ("Patching texture node %d/%d to tx=%d\n",
+ old_node->id, old_node->output_id,
+ new_texture);
+#endif
+ append_uint32 (output, BROADWAY_NODE_OP_PATCH_TEXTURE);
+ append_uint32 (output, old_node->output_id);
+ append_uint32 (output, new_texture);
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ }
+}
+
static BroadwayNode *
append_node_ops (BroadwayOutput *output,
* Except we avoid this for reused node as those make more sense to reuse deeply.
*/
- if (old_node && broadway_node_equal (node, old_node) && !old_node->reused)
+ if (old_node && should_reuse_node (output, node, old_node))
{
int old_i = 0;
BroadwayNode *last_child = NULL;
const BROADWAY_NODE_OP_INSERT_NODE = 0;
const BROADWAY_NODE_OP_REMOVE_NODE = 1;
const BROADWAY_NODE_OP_MOVE_AFTER_CHILD = 2;
+const BROADWAY_NODE_OP_PATCH_TEXTURE = 3;
+const BROADWAY_NODE_OP_PATCH_TRANSFORM = 4;
const BROADWAY_OP_GRAB_POINTER = 'g';
const BROADWAY_OP_UNGRAB_POINTER = 'u';
const DISPLAY_OP_RESIZE_NODE = 8;
const DISPLAY_OP_RESTACK_SURFACES = 9;
const DISPLAY_OP_DELETE_SURFACE = 10;
+const DISPLAY_OP_CHANGE_TEXTURE = 11;
+const DISPLAY_OP_CHANGE_TRANSFORM = 12;
// GdkCrossingMode
const GDK_CROSSING_NORMAL = 0;
return utf8_to_string (utf8);
}
+TransformNodes.prototype.decode_transform = function() {
+ var transform_type = this.decode_uint32();
+
+ if (transform_type == 0) {
+ var point = this.decode_point();
+ return "translate(" + px(point.x) + "," + px(point.y) + ")";
+ } else if (transform_type == 1) {
+ var m = new Array();
+ for (var i = 0; i < 16; i++) {
+ m[i] = this.decode_float ();
+ }
+
+ return "matrix3d(" +
+ m[0] + "," + m[1] + "," + m[2] + "," + m[3]+ "," +
+ m[4] + "," + m[5] + "," + m[6] + "," + m[7] + "," +
+ m[8] + "," + m[9] + "," + m[10] + "," + m[11] + "," +
+ m[12] + "," + m[13] + "," + m[14] + "," + m[15] + ")";
+ } else {
+ alert("Unexpected transform type " + transform_type);
+ }
+}
+
function args() {
var argsLength = arguments.length;
var strings = [];
case BROADWAY_NODE_TRANSFORM:
{
- var transform_type = this.decode_uint32();
- var transform_string;
-
- if (transform_type == 0) {
- var point = this.decode_point();
- transform_string = "translate(" + px(point.x) + "," + px(point.y) + ")";
- } else if (transform_type == 1) {
- var m = new Array();
- for (var i = 0; i < 16; i++) {
- m[i] = this.decode_float ();
- }
-
- transform_string =
- "matrix3d(" +
- m[0] + "," + m[1] + "," + m[2] + "," + m[3]+ "," +
- m[4] + "," + m[5] + "," + m[6] + "," + m[7] + "," +
- m[8] + "," + m[9] + "," + m[10] + "," + m[11] + "," +
- m[12] + "," + m[13] + "," + m[14] + "," + m[15] + ")";
- }
+ var transform_string = this.decode_transform();
var div = this.createDiv(id);
div.style["transform"] = transform_string;
var toMove = this.nodes[toMoveId];
this.display_commands.push([DISPLAY_OP_INSERT_AFTER_CHILD, parent, previousChild, toMove]);
break;
+ case BROADWAY_NODE_OP_PATCH_TEXTURE:
+ var textureNodeId = this.decode_uint32();
+ var textureNode = this.nodes[textureNodeId];
+ var textureId = this.decode_uint32();
+ var texture = textures[textureId].ref();
+ this.display_commands.push([DISPLAY_OP_CHANGE_TEXTURE, textureNode, texture]);
+ break;
+ case BROADWAY_NODE_OP_PATCH_TRANSFORM:
+ var transformNodeId = this.decode_uint32();
+ var transformNode = this.nodes[transformNodeId];
+ var transformString = this.decode_transform();
+ this.display_commands.push([DISPLAY_OP_CHANGE_TRANSFORM, transformNode, transformString]);
+ break;
}
+
}
}
var id = cmd[1];
delete surfaces[id];
break;
-
+ case DISPLAY_OP_CHANGE_TEXTURE:
+ var image = cmd[1];
+ var texture = cmd[2];
+ // We need a new closure here to have a separate copy of "template" for each iteration...
+ function a_block(t) {
+ image.src = t.url;
+ // Unref blob url when loaded
+ image.onload = function() { t.unref(); };
+ }(texture);
+ break;
+ case DISPLAY_OP_CHANGE_TRANSFORM:
+ var div = cmd[1];
+ var transform_string = cmd[2];
+ div.style["transform"] = transform_string;
+ break;
default:
alert("Unknown display op " + command);
}